package lockDemo.synchronizeDemo;

import org.apache.log4j.lf5.viewer.LogTable;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Ajie
 * @date 2023/8/7
 * @function 在上述示例中，生产者线程调用 produce 方法来生产物品，而消费者线程调用 consume 方法来消费物品。
 * <p>
 * 当队列满时，生产者线程会被阻塞，直到消费者线程消费了一些物品。
 * 相反，当队列为空时，消费者线程会被阻塞，直到生产者线程生产了一些物品。
 * <p>
 * 总结：条件变量（如 wait() 和 notify()）允许线程等待某个条件成立，同时释放已经获得的锁，从而使其他线程可以进入同步代码块或方法并更改共享资源的状态。这是一种强大的同步机制，用于协调多个线程之间的工作。
 */
public class Sync_Wait_Notify_Queue {

    private final List<Object> items = new ArrayList<>();
    private final int MAX_SIZE = 10;
    private final Object lock = new Object(); // 特定的锁对象

    public void produce(Object item) {
        synchronized (lock) {
            while (items.size() == MAX_SIZE) {
                try {
                    System.out.println("Sync_Wait_Notify_Queue:produce:货满了。等待消费。");
                    lock.wait(); // 使用特定的锁对象等待
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
            System.out.println("Sync_Wait_Notify_Queue:produce:生产");
            items.add(item);
            lock.notify(); // 使用特定的锁对象通知
        }
    }

    public Object consume() {
        synchronized (lock) {
            while (items.isEmpty()) {
                try {
                    System.out.println("Sync_Wait_Notify_Queue:consume:没货了。等待。");
                    lock.wait(); // 使用特定的锁对象等待
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
            Object item = items.remove(0);
            lock.notify(); // 使用特定的锁对象通知
            return item;
        }
    }
}
